import re
import time
from logging import DEBUG

from appium.webdriver.common.appiumby import AppiumBy
import logging

from ..order_page.order_page import OrderPage
from ...constants.common_sequence import LANGUAGE_SEQUENCE, SWITCH_ENV

from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions import interaction
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput

from ...exception.customer_exception import CustomerException
from ...models.enums.app_http_code_enum import AppHttpCodeEnum

logger = logging.getLogger(__name__)

# TODO 针对异常插入页面的异常处理（突然的应用浮于上层）
"""
Description
    登录页的登录功能
    1. 包括商家登录
    2. 包括店员登录
    3. 包括切换语言
"""


class LoginPage(object):

    def __init__(self, client):
        self.driver = client.driver
        self.width = client.width
        self.height = client.height
        self.client = client

    """
    SubPage Function
    """

    def switch_env_detail(self, env_name):
        """
        切换环境详情
        Params:
        -env_name:环境名称
        """
        # 切换请求地址
        env_list = self.driver.find_elements(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_name')
        env_list[0].click()
        self.driver.implicitly_wait(4)
        self.driver.find_element(AppiumBy.XPATH, f'//*[contains(@text,"{env_name}")]').click()
        # 切换订阅主题
        env_list = self.driver.find_elements(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_name')
        env_list[1].click()
        self.driver.implicitly_wait(4)
        self.driver.find_element(AppiumBy.XPATH, f'//*[contains(@text,"{env_name}")]').click()
        self.driver.implicitly_wait(4)
        # 保存
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/btn_confirm').click()
        time.sleep(2)
        return self

    """
    Button Function
    """

    def switch_env(self, env_name):
        """
        切换环境
        Params:
        -name:环境名称
        """
        try:
            for i in range(7):
                self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/iv_login').click()
            self.driver.implicitly_wait(4)
            self.switch_env_detail(env_name)
            self.driver.implicitly_wait(3)
        except Exception as e:
            raise CustomerException(AppHttpCodeEnum.SWITCH_ENV_FILE)
        return self

    # def insert_pwd(self, number_seq):
    #     """
    #     输入店员密码
    #     Params:
    #     -number_seq: 密码序列
    #     """
    #     number_seq_list = list(number_seq)
    #     for num in number_seq_list:
    #         num = int(num)
    #         element = self.driver.find_element(AppiumBy.ID, value="pass_code_view")
    #         width = element.size["width"]
    #         height = element.size["height"]
    #         x_position, y_position = element.location["x"], element.location["y"] + int(height) / 5
    #         position_x_tag, position_y_tag = num % 3, num / 3 + 1
    #         if position_x_tag == 0:
    #             position_x_tag = 3
    #         if num % 3 == 0:
    #             position_y_tag = num / 3
    #         actions = ActionChains(self.driver)
    #         actions.w3c_actions = ActionBuilder(self.driver, mouse=PointerInput(interaction.POINTER_TOUCH, "touch"))
    #         actions.w3c_actions.pointer_action.move_to_location(int(x_position + (position_x_tag - 1) * width / 3),
    #                                                             int(y_position + (position_y_tag - 1) * height / 5))
    #         actions.w3c_actions.pointer_action.pointer_down()
    #         actions.w3c_actions.pointer_action.pause(0.1)
    #         actions.w3c_actions.pointer_action.release()
    #         actions.perform()
    #     return self

    def insert_pwd(self, number_seq):
        """
        输入店员密码
        Params:
        -number_seq
        """
        keyboard_element = self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/pass_code_view')
        width = keyboard_element.size['width']
        height = keyboard_element.size['height']
        from_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", keyboard_element.get_attribute("bounds")).group(1).split(',')
        to_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", keyboard_element.get_attribute("bounds")).group(2).split(',')
        from_x, from_y, to_x, to_y = int(from_element_location[0]), int(from_element_location[1]) + height // 5 + 3, int(to_element_location[0]), int(to_element_location[1])
        unit_x, unit_y = int(width / 3), int(height / 4)
        for num in number_seq:
            if num.isdigit() and int(num) != 0:
                x = from_x + ((int(num) % 3 if int(num) % 3 != 0 else 3) - 1) * unit_x + 30
                step = (int(num)) // 3 if (int(num)) % 3 != 0 else (int(num)) // 3 - 1
                y = from_y + step * unit_y + 16
            elif num.isdigit() and int(num) == 0:
                x = from_x + unit_x + 16
                y = from_y + 3 * unit_y + 16
            else:
                x = from_x + 16
                y = from_y + 3 * unit_y + 16
            actions = ActionChains(self.driver)
            actions.w3c_actions = ActionBuilder(self.driver, mouse=PointerInput(interaction.POINTER_TOUCH, "touch"))
            # 计算X,Y值
            actions.w3c_actions.pointer_action.move_to_location(x, y)
            actions.w3c_actions.pointer_action.pointer_down()
            actions.w3c_actions.pointer_action.pause(0.1)
            actions.w3c_actions.pointer_action.release()
            actions.perform()
        return self

    def business_login(self, applet_id, applet_pwd):
        """
        商家登录
        Params:
        -applet_id: 商家ID
        -applet_pwd: 商家密码
        """
        try:
            self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/et_login_user').send_keys(applet_id)
            self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/et_login_password').send_keys(applet_pwd)
            self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_sign_in').click()
            time.sleep(1)
        except Exception as e:
            raise CustomerException(AppHttpCodeEnum.BUSINESS_LOGIN_FAIL)
        return self

    def clerk_login(self, clerk_name, clerk_pwd):
        """
        登录
        Params:
        -applet_id: 用户名
        -applet_pwd: 密码
        """
        try:
            self.driver.find_element(by=AppiumBy.XPATH,
                                     value=f'//*[@resource-id="{SWITCH_ENV}:id/tv_name" and @text="{clerk_name}"]').click()
            self.insert_pwd(clerk_pwd)
            time.sleep(8)
        except Exception as e:
            raise CustomerException(AppHttpCodeEnum.CLERK_LOGIN_FAIL)
        return OrderPage(self.client)

    # TODO 切换语言时可以根据速度进行选择
    def switch_language(self, language):
        """
        切换语言
        Params:
        -language:语言
        """
        # 找到切换语言的按钮,并点击
        try:
            self.driver.find_element(AppiumBy.ID, f"{SWITCH_ENV}:id/cl_login_language").click()
            self.driver.implicitly_wait(2)
            # 切换语言
            element = self.driver.find_element(AppiumBy.ID, value="pickerview")
            # 获取宽和高
            width = element.size['width']
            height = element.size['height']
            logger.log(DEBUG, msg=f"宽度: {width}, 高度: {height}")

            # NODE 先回到最顶层，是通过时间进行控制的
            self.driver.swipe(self.width / 2, self.height - height / 2, self.width / 2,
                              self.height - height / 2 + height / 5, duration=100)  # duration 以毫秒为单位
            index = LANGUAGE_SEQUENCE.index(language)
            # NOTE 移动滑块
            for i in range(index):
                self.driver.swipe(self.width / 2, self.height - height / 2, self.width / 2,
                                  self.height - height / 2 - height / 5, duration=500)  # duration 以毫秒为单位

            time.sleep(1)
            # 点击确认
            self.driver.find_element(AppiumBy.ID, value="tv_confirm").click()
            time.sleep(3)
        except Exception as e:
            raise CustomerException(AppHttpCodeEnum.SWITCH_LANGUAGE_FILE)
        return self
